package com.access.boot.apisdk;

import com.access.boot.apisdk.util.HandlerMethod;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import okhttp3.Headers;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;

import java.io.Serializable;
import java.time.Instant;
import java.util.Date;
import java.util.List;

/**
 * @author Yangzhen
 * @date 2023/1/11 18:27
 * @since 1.0.0
 */
@FieldDefaults(level = AccessLevel.PUBLIC)
public class RequestContext implements Serializable {

    public static final MediaType APPLICATION_JSON = MediaType.get("application/json; charset=utf-8");

    HandlerMethod handlerMethod;
    String path;
    SdkContext sdkContext;
    HttpUrl baseUrl;
    Request.Builder requestBuilder;
    HttpUrl.Builder httpUrlBuilder;
    Headers.Builder headersBuilder;
    RequestBody requestBody;

    public RequestContext(HandlerMethod handlerMethod, SdkContext sdkContext) {
        this.handlerMethod = handlerMethod;
        this.sdkContext = sdkContext;
        this.headersBuilder = new Headers.Builder();
        this.requestBuilder = new Request.Builder();
        this.baseUrl = HttpUrl.parse(sdkContext.host).resolve(handlerMethod.getOpenapi());
        this.httpUrlBuilder = this.baseUrl.newBuilder();
        this.path = this.handlerMethod.getOpenapi();
    }

    public void addHeader(String name, Object value) {
        if (value == null) {
            return;
        }
        if (value instanceof String) {
            this.headersBuilder.add(name, String.valueOf(value));
        } else if (value instanceof Date) {
            this.headersBuilder.add(name, (Date) value);
        } else if (value instanceof Instant) {
            this.headersBuilder.add(name, (Instant) value);
        } else {
            return;
        }
    }

    public void addQueryParameter(String name, String value) {
        this.httpUrlBuilder.addQueryParameter(name, value);
    }

    /**
     * 设置path参数
     *
     * @param index path参数下标
     * @param value 值
     */
    public void setPathValue(int index, String value) {
        this.httpUrlBuilder.setPathSegment(index, value);
    }

    public List<String> getPathSegments() {
        return this.baseUrl.pathSegments();
    }

    public Request getRequest() {
        Request build = requestBuilder
                .headers(headersBuilder.build())
                .url(httpUrlBuilder.build())
                .method(handlerMethod.getRequestMethod(), requestBody)
                .build();
        return build;
    }

    public void toRequestBody(String json) {
        this.requestBody = RequestBody.create(json, APPLICATION_JSON);
    }
}
